package com.piece.core.framework.util.net;

import com.piece.core.framework.util.string.StringUtil;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.nio.charset.Charset;

public class URLDecoder implements Serializable {

    public static String decode(String str, Charset charset) {
        return decode(str, charset, true);
    }

    public static String decode(String str, Charset charset, boolean isPlusToSpace) {
        byte[] data = decode(StringUtil.getBytes(str, charset), isPlusToSpace);
        if (null == data) {
            return null;
        } else {
            return null == charset ? new String(data) : new String(data, charset);
        }
    }

    public static byte[] decode(byte[] bytes) {
        return decode(bytes, true);
    }

    public static byte[] decode(byte[] bytes, boolean isPlusToSpace) {
        if (bytes == null) {
            return null;
        } else {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream(bytes.length);

            for(int i = 0; i < bytes.length; ++i) {
                int b = bytes[i];
                if (b == 43) {
                    buffer.write(isPlusToSpace ? 32 : b);
                } else if (b == 37) {
                    if (i + 1 < bytes.length) {
                        int u = Character.digit(bytes[i + 1], 16);
                        if (u >= 0 && i + 2 < bytes.length) {
                            int l = Character.digit(bytes[i + 2], 16);
                            if (l >= 0) {
                                buffer.write((char)((u << 4) + l));
                                i += 2;
                                continue;
                            }
                        }
                    }

                    buffer.write(b);
                } else {
                    buffer.write(b);
                }
            }

            return buffer.toByteArray();
        }
    }

    public static String decodeForPath(String str, Charset charset) {
        return decode(str, charset, false);
    }
}